package com.heima.leetcode.practice;

/**
 * @author 勾新杰
 * @version 1.0
 * @description: leetcode 48 旋转图像
 * @date 2024/12/14 13:11
 */
public class E48 {

    /*
     * [1,2,3]      [7,4,1]
     * [4,5,6]      [8,5,2]
     * [7,8,9]      [9,6,3]
     * 换算关系就是：
     * 同列的翻过去作为同行，新的行坐标就是原来的列坐标
     * 而且翻过去后列坐标的顺序就是原来行坐标的倒序
     */

    /**
     * <h3>方法一：多用一个二维数组和下标换算关系</h3>
     *
     * @param matrix 二维数组
     */
    public void rotate1(int[][] matrix){
        int n = matrix.length;
        int[][] temp = new int[n][n];
        for(int i = 0; i < n; i++)
            System.arraycopy(matrix[i], 0, temp[i], 0, n);
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                matrix[j][n - i - 1] = temp[i][j];
    }

    /**
     * <h3>方法二：原地修改</h3>
     *
     * @param matrix 二维数组
     */
    public void rotate2(int[][] matrix) {
        // 获取矩阵的大小，由于是方阵，所以只需要取一行的长度
        int n = matrix.length;
        // 外层循环负责逐层旋转，从外层到内层
        // i表示当前正在处理的层
        for(int i = 0; i < n >> 1; i++){
            // 这里的last既可以代表当前行对称的数，也可以代表与当前行对称的行，也可以表示当前层最后一个元素
            int last = n - i - 1;
            // 内层循环负责处理当前层的每个元素
            // 从当前层的第一个元素开始，到最后一个元素之前结束
            for(int j = i; j < n - i - 1; j++){
                // 计算当前元素相对于当前层起始位置的偏移量
                int offset = j - i;
                // 保存当前正在处理的元素，作为旋转的起始点
                int temp = matrix[i][j];
                // 将左侧的值移动到当前位置
                matrix[i][j] = matrix[last - offset][i];
                // 将右侧的值移动到左侧的位置
                matrix[last - offset][i] = matrix[last][last - offset];
                // 将底部的值移动到右侧的位置
                matrix[last][last - offset] = matrix[i + offset][last];
                // 将顶部的值（保存在temp中）移动到底部的位置
                matrix[i + offset][last] = temp;
            }
        }
    }
}
